import os
import traceback
import shutil
import logging
from pathlib import Path
from config import Config

# 导入拆分后的模块
from ..module.structure import clear_folder_contents, create_output_folders,process_directory
from ..module.source_processor import process_source1_document, process_source1_lockout, process_source1_approval, process_source1_dvp, process_source2
from ..module.pdf_operations import save_single_page, replace_page_in_pdf
from ..module.extraction import contains_keywords
from ..utils.update_page_size import resize_pdfs_to_a4
from ..utils.logger import pdf_logger
from PyPDF2 import PdfReader


def reprocess_unmatched_pages():
    """
    后处理函数：重新检查未插入签字页文件夹中的PDF文件，
    如果内容匹配MAIN_OTHER_KEYWORDS，则将其移动到对应的文件夹
    :return: 移动的文件数量
    """
    moved_count = 0
    uninserted_dir = Path(Config.UNINSERTED_SIGN_DIR)
    
    if not uninserted_dir.exists():
        print(f"⚠️ 未插入签字页文件夹不存在：{uninserted_dir}")
        return moved_count
    
    print(f"\n{'='*70}")
    print(f"🔍 开始重新检查未插入签字页文件夹中的MAIN_OTHER_KEYWORDS文件")
    print(f"{'='*70}")
    
    # 遍历未插入签字页文件夹中的所有PDF文件
    for pdf_file in uninserted_dir.glob("*.pdf"):
        try:
            # 读取PDF文件内容
            reader = PdfReader(str(pdf_file))
            text = ""
            for page in reader.pages:
                text += page.extract_text() or ""
            
            if not text:
                print(f"⚠️ 无法提取文本：{pdf_file.name}")
                continue
            
            # 检查是否匹配MAIN_OTHER_KEYWORDS
            matched_keyword = contains_keywords(text, Config.MAIN_OTHER_KEYWORDS)
            if matched_keyword:
                print(f"🔍 发现匹配文件：{pdf_file.name} → 关键词[{matched_keyword}]")
                
                # 在原始项目资料文件夹中查找对应关键词的文件夹
                source_dir1_path = Path(Config.SOURCE_DIR1)
                if source_dir1_path.exists():
                    # 递归遍历源目录1中的所有文件夹，查找包含关键词的文件夹
                    target_folder = None
                    for root, dirs, files in os.walk(source_dir1_path):
                        for dir_name in dirs:
                            if matched_keyword in dir_name:
                                target_folder = Path(root) / dir_name
                                break
                        if target_folder:
                            break
                    
                    if target_folder:
                        # 找到匹配文件夹，移动文件
                        target_path = target_folder / pdf_file.name
                        try:
                            shutil.move(str(pdf_file), str(target_path))
                            moved_count += 1
                            print(f"✅ 移动文件：{pdf_file.name} → {target_folder}")
                        except Exception as e:
                            print(f"❌ 移动文件失败：{pdf_file.name} - {str(e)}")
                    else:
                        # 没有找到对应文件夹
                        print(f"⚠️ 未找到对应文件夹：{matched_keyword}，文件保留在原位置")
                else:
                    print(f"⚠️ 源目录1不存在：{source_dir1_path}")
            
        except Exception as e:
            print(f"❌ 处理文件失败：{pdf_file.name} - {str(e)}")
            continue
    
    print(f"📊 后处理完成：共移动{moved_count}个MAIN_OTHER_KEYWORDS文件")
    return moved_count


# -------------------------- 核心功能：主流程 --------------------------
def main():


    # 1. 格式化待插入的PDF文件夹中的PDF文件为A4大小
    resize_pdfs_to_a4()
    pdf_logger.info(f"✅ 待插入的PDF文件夹中的PDF文件已格式化-A4大小")

    # 2. 运行前清空指定文件夹
    pdf_logger.info(f"✅ 开始清空历史文件")
    clear_folder_contents(Config.INSERTED_SIGN_DIR)  # 清空已插入签字页文件夹
    clear_folder_contents(Config.UNINSERTED_SIGN_DIR)  # 清空未插入签字页文件夹

    # 3. 创建输出文件夹（确保文件夹存在）
    create_output_folders()
    pdf_logger.info(f" "*80 + "\n")
    
    
    # 4. 处理源目录1：提取待替换的页
    pdf_logger.info(f"🚀 开始处理【源目录1】")
    source1_files = process_directory(Config.SOURCE_DIR1, Config.SKIP_FOLDERS, skip_signature_versions=False)
    source1_data = []
    for pdf_path in source1_files:
        file_name = os.path.basename(pdf_path)
        # 检查是否包含主文件关键词（列表）
        if any(kw in file_name for kw in Config.MAIN_DOCUMENT_KEYWORDS):
            source1_data.extend(process_source1_document(pdf_path))
        # 检查是否包含审批文件关键词（列表）
        elif any(kw in file_name for kw in Config.MAIN_APPROVAL_KEYWORDS):
            source1_data.extend(process_source1_approval(pdf_path))
        # 检查是否包含特殊关键词1（列表）
        elif any(kw in file_name for kw in Config.SPECIAL_KEYWORDS_DVP):
            source1_data.extend(process_source1_dvp(pdf_path))
        # 检查是否包含特殊关键词1（列表）
        elif any(kw in file_name for kw in Config.SPECIAL_KEYWORDS_LOCKOUT):
            source1_data.extend(process_source1_lockout(pdf_path))
        else:
            pdf_logger.info(f"⚠️ 未匹配到任何关键词：{file_name}")         
    if not source1_data:
        pdf_logger.warning(f"⚠️ 【源目录1】处理完成：未找到任何待替换页，终止流程！")
        return
    pdf_logger.info(f"✅ 【源目录1】处理总结：共{len(source1_data)}条待替换页数据\n")

    # 5. 处理源目录2：提取待替换的签字页
    pdf_logger.info(f"🚀 开始处理【源目录2】")
    source2_files = process_directory(Config.SOURCE_DIR2, Config.SKIP_FOLDERS, skip_signature_versions=False)
    source2_data = []
    for pdf_path in source2_files:
        source2_data.extend(process_source2(pdf_path))
    
    if not source2_data:
        pdf_logger.warning(f"⚠️ 【源目录2】处理完成：未找到任何签字页，终止流程！")
        return
    pdf_logger.info(f"✅ 【源目录2】处理总结：共{len(source2_data)}条签字页\n")





    # 修改6. 匹配与替换部分
    matched_indices = set()
    total_matched = 0

    # 为每个源1文件维护单独的已匹配索引
    file_matched_indices = {}

    for s1 in source1_data:
        s1_file = s1["file_name"]
        s1_keyword = s1["keyword"]
        s1_version = s1["version"]
        s1_page_idx = s1["page_num"]
        s1_page_show = s1["page_num_show"]
        s1_original_path = s1["full_path"]

        # 初始化该文件的匹配索引集合
        if s1_original_path not in file_matched_indices:
            file_matched_indices[s1_original_path] = set()

        print(f"\n📌 正在匹配目标源1页：{s1_file}（第{s1_page_show}页 | {s1_keyword} | v{s1_version}）")

        for s2_idx, s2 in enumerate(source2_data):
            # 检查该签字页是否已被当前文件使用过
            if s2_idx in file_matched_indices[s1_original_path]:
                continue
            s2_file = s2["file_name"]
            s2_keyword = s2["keyword"]
            s2_version = s2["version"]
            s2_page_show = s2["page_num_show"]
            s2_page_object = s2["page_object"]

            # 跳过没有关键词的页面（无法匹配）
            if not s2_keyword:
                continue

            # 对于锁定批准表类型
            if s1_keyword in Config.SPECIAL_KEYWORDS_LOCKOUT and s2_keyword in Config.SPECIAL_KEYWORDS_LOCKOUT:
                # a.验证关键词完全一致
                if s1_keyword != s2_keyword:
                    print(f"⚠️ 锁定批准表关键词不匹配，跳过：源1[{s1_keyword}] ≠ 源2[{s2_keyword}]")
                    continue
                # b.验证页码匹配
                s1_pagenum = s1["page_number"]
                s2_pagenum = s2.get("page_number")
                if s1_pagenum == s2_pagenum:
                    match_ok = True
                    print(f"✅ 源2新页匹配（特殊锁定批准表类型）：{s2_file}（第{s2_page_show}页 | 页码[{s2_pagenum}]）")

            # 对于DVP类型
            if s1_keyword in Config.SPECIAL_KEYWORDS_DVP and s2_keyword in Config.SPECIAL_KEYWORDS_DVP:
                # a.验证关键词完全一致
                if s1_keyword != s2_keyword:
                    print(f"⚠️ DVP关键词不匹配，跳过：源1[{s1_keyword}] ≠ 源2[{s2_keyword}]")
                    continue
                # b.验证版本号匹配
                if not s2_version or s1_version != s2_version:
                    print(f"⚠️ 版本号不匹配，跳过：源1[v{s1_version}] ≠ 源2[v{s2_version}]")
                    continue
                
                # c.验证签字页类型       
                s1_sig = s1["signature_type"]
                s2_sig = s2.get("signature_type")
                if s1_sig == s2_sig:
                    match_ok = True
                    print(f"✅ 源2新页匹配（签字类型）：{s2_file}（第{s2_page_show}页 | 签字类型[{s2_sig}]）")

            # 对于document类型
            if s1_keyword in Config.MAIN_DOCUMENT_KEYWORDS and s2_keyword in Config.MAIN_DOCUMENT_KEYWORDS:
                # a.验证关键词完全一致
                if s1_keyword != s2_keyword:
                    print(f"⚠️ 文档关键词不匹配，跳过：源1[{s1_keyword}] ≠ 源2[{s2_keyword}]")
                    continue

                # b.验证版本号匹配
                if not s2_version or s1_version != s2_version:
                    print(f"⚠️ 版本号不匹配，跳过：源1[v{s1_version}] ≠ 源2[v{s2_version}]")
                    continue
                
                # c.验证页码匹配       
                s1_pagenum = s1["page_number"]
                s2_pagenum = s2.get("page_number")
                if s1_pagenum == s2_pagenum:
                    match_ok = True
                    print(f"✅ 文档页码匹配：{s2_file}（第{s2_page_show}页 | 页码[{s2_pagenum}]）")


            # 对于approval类型
            if s1_keyword in Config.MAIN_APPROVAL_KEYWORDS and s2_keyword in Config.MAIN_APPROVAL_KEYWORDS:
                # a.验证关键词完全一致
                if s1_keyword != s2_keyword:
                    print(f"⚠️ 审批关键词不匹配，跳过：源1[{s1_keyword}] ≠ 源2[{s2_keyword}]")
                    continue

                # b.验证版本号匹配
                if not s2_version or s1_version != s2_version:
                    print(f"⚠️ 版本号不匹配，跳过：源1[v{s1_version}] ≠ 源2[v{s2_version}]")
                    continue
                
                # c.验证页码匹配       
                s1_pagenum = s1["page_number"]
                s2_pagenum = s2.get("page_number")
                if s1_pagenum == s2_pagenum:
                    match_ok = True
                    print(f"✅ 审批页码匹配：{s2_file}（第{s2_page_show}页 | 页码[{s2_pagenum}]）")


            if match_ok:
                # 替换页面的代码保持不变
                replace_ok = replace_page_in_pdf(
                    original_pdf_path=s1_original_path,
                    page_to_insert=s2_page_object,
                    target_page_idx=s1_page_idx,
                    output_path=s1_original_path
                )

                # 验证替换是否成功
                if replace_ok:

                    # 获取s2的页码信息，如果不存在则使用None
                    s2_page_number = s2.get("page_number")

                    # 区分版本号不存在（字段缺失）和存在但为None（文档类型无版本号）
                    if s2_version is None:
                        version_str = "不适用"  # 文档类型本身无版本号概念
                    elif s2_version == "":
                        version_str = "未识别版本号"  # 字段存在但内容为空
                    else:
                        version_str = f"v{s2_version}"  # 正常版本号


                    # 区分页码不存在（字段缺失）和存在但为None（文档类型无页码）
                    if s2_page_number is None:
                        page_num_str = "不适用"  # 文档类型本身无页码概念
                    elif s2_page_number == "":
                        page_num_str = "未识别页码"  # 字段存在但内容为空
                    else:
                        page_num_str = s2_page_number  # 正常页码


                        
                    # 清理页码字符串中的路径分隔符，避免转义问题
                    clean_page_num = str(page_num_str).replace('/', '-').replace('\\', '-') if page_num_str else "无页码"
                    # 移除文件名中的冒号，避免Windows系统非法字符问题
                    inserted_page_name = f"第{s2_page_show}页_关键词[{s2_keyword}]_版本[{version_str}]_页码[{clean_page_num}]_已替换.pdf"
                    inserted_page_path = Path(Config.INSERTED_SIGN_DIR)/inserted_page_name
                    save_single_page(s2_page_object, inserted_page_path)

                    # 将匹配的索引添加到当前文件的集合中，而不是全局集合
                    file_matched_indices[s1_original_path].add(s2_idx)
                    total_matched += 1
                    print(f"🔗 替换完成（累计{total_matched}组）：{s1_file}第{s1_page_show}页 ← {s2_file}第{s2_page_show}页")
                break



    # 9. 处理源2所有未匹配页面
    print(f"\n{'='*70}")
    print(f"📊 开始处理【源2未匹配新页】（全部保存至未插入签字页文件夹）")
    print(f"{'='*70}")
    unmatched_count = 0
    # 遍历所有源2页面
    for s2_idx, s2 in enumerate(source2_data):
        # 检查该页面是否被任何文件使用过
        used = False
        for file_indices in file_matched_indices.values():
            if s2_idx in file_indices:
                used = True
                break
        
        # 只处理未匹配的页面
        if not used:
            s2_page_show = s2.get("page_num_show")
            s2_keyword = s2.get("keyword") or "无关键词"
            s2_version = s2.get("version")
            s2_page_number = s2.get("page_number")

            # 生成更详细的文件名，包含未匹配原因
            reason = []
            
            # 特殊处理锁定批准表
            if s2_keyword in Config.SPECIAL_KEYWORDS_LOCKOUT:
                # 锁定批准表：只关心关键词和页码，不关心版本号
                if not s2["has_keyword"]:
                    reason.append("无关键词")
                if not s2.get("page_number"):
                    reason.append("无页码")
                else:
                    # 有关键词但未匹配成功，说明s1中没有对应的锁定批准表
                    reason.append("无匹配项")
            
            # 特殊处理DVP（数据核查计划）
            elif s2_keyword in Config.SPECIAL_KEYWORDS_DVP:
                # DVP：有关键词和版本号，但不需要页码，需要签字类型匹配
                if not s2["has_keyword"]:
                    reason.append("无关键词")
                if not s2.get("version"):
                    reason.append("无版本号")
                if s2["has_keyword"] and s2.get("version"):
                    # 有关键词和版本号但未匹配成功，说明s1中没有对应的签字类型
                    reason.append("无匹配项")
            
            else:
                # 其他文档类型：需要关键词、版本号和页码
                if not s2["has_keyword"]:
                    reason.append("无关键词")
                if not s2.get("version"):
                    reason.append("无版本号")
                if not s2.get("page_number"):
                    reason.append("无页码")
                # 只有同时具备关键词、版本号和页码，才可能存在"无匹配项"的情况
                if s2["has_keyword"] and s2.get("version") and s2.get("page_number"):
                    reason.append("无匹配项")

            reason_str = "_".join(reason)
            # 区分版本号不存在（字段缺失）和存在但为None（文档类型无版本号）
            if s2_version is None:
                version_str = "NA"  # 文档类型本身无版本号概念
            elif s2_version == "":
                version_str = "无版本号"  # 字段存在但内容为空
            else:
                version_str = f"v{s2_version}"  # 正常版本号
            
            # 区分页码不存在（字段缺失）和存在但为None（文档类型无页码）
            if s2_page_number is None:
                page_num_str = "NA"  # 文档类型本身无页码概念
            elif s2_page_number == "":
                page_num_str = "无页码"  # 字段存在但内容为空
            else:
                page_num_str = s2_page_number  # 正常页码
            # 清理页码字符串中的路径分隔符，避免转义问题
            clean_page_num = str(page_num_str).replace('/', '-').replace('\\', '-')
            # 构建简洁的文件名，移除原始文件名部分
            unmatched_page_name = f"第{s2_page_show}页_关键词[{s2_keyword}]_版本[{version_str}]_页码[{clean_page_num}]_{reason_str}.pdf"

            # 特殊处理MAIN_OTHER_KEYWORDS - 尝试放入对应文件夹
            target_folder_path = None
            if s2_keyword in Config.MAIN_OTHER_KEYWORDS:
                # 在原始项目资料文件夹中递归查找对应关键词的文件夹
                source_dir1_path = Path(Config.SOURCE_DIR1)
                if source_dir1_path.exists():
                    # 递归遍历所有子文件夹，查找包含关键词的文件夹
                    for root, dirs, files in os.walk(source_dir1_path):
                        for dir_name in dirs:
                            if s2_keyword in dir_name:
                                target_folder_path = Path(root) / dir_name
                                print(f"📁 找到匹配文件夹：{target_folder_path}")
                                break
                        if target_folder_path:
                            break
            
            # 如果找到对应文件夹，保存到该文件夹；否则保存到未插入签字页目录
            if target_folder_path:
                unmatched_page_path = target_folder_path / unmatched_page_name
                print(f"📄 保存到对应文件夹：{target_folder_path}")
            else:
                unmatched_page_path = Path(Config.UNINSERTED_SIGN_DIR) / unmatched_page_name
            if save_single_page(s2["page_object"], unmatched_page_path):
                unmatched_count += 1
                print(f"ℹ️ 已保存未匹配页面：{os.path.basename(unmatched_page_path)}")

    print(f"📊 未匹配新页处理完成：共{unmatched_count}个未匹配页面（保存路径：{Config.UNINSERTED_SIGN_DIR}）")

    # 10. 后处理：重新检查未匹配页面中的MAIN_OTHER_KEYWORDS
    moved_count = reprocess_unmatched_pages()

    # 11. 打印最终统计
    print(f"\n{'='*80}")
    print(f"📋 PDF匹配与替换工具 - 流程完成")
    print(f"{'='*80}")
    print(f"✅ 成功替换组数：{total_matched}")
    print(f"⚠️ 源2未匹配新页数：{unmatched_count}")
    print(f"🔄 后处理移动MAIN_OTHER_KEYWORDS文件数：{moved_count}")
    print(f"📥 源1待替换旧页总数：{len(source1_data)}")
    print(f"📥 源2待替换新页总数：{len(source2_data)}")
    print(f"💾 已替换新页备份路径：{Config.INSERTED_SIGN_DIR}")
    print(f"💾 未匹配新页备份路径：{Config.UNINSERTED_SIGN_DIR}")


# -------------------------- 程序入口 --------------------------
if __name__ == "__main__":

    try:
        # 主流程
        main()
    except Exception as e:
        print(f"\n{'='*50}")
        print(f"❌ 程序运行出错 - 终止")
        print(f"{'='*50}")
        print(f"📝 错误原因：{str(e)}")
        print(f"📝 错误详情：")
        traceback.print_exc()
        print(f"{'='*50}")